条件を満たす行を取り除く
Posted feedbacks - Nested
Flatten Hidden1 2 3 | while ARGF.gets
puts $_ unless $_[0] == ?#
end
|
考え方は同じですが,Rubyっぽくなるように心がけてみました
1 2 3 | ARGF.read.each_line do |line|
puts line unless line.index('#') == 0
end
|
1 | print grep!/^#/,<>
|
ワンライナーで
1 | % ruby -ne 'puts $_ unless $_ =~ /^#/'
|
細かい点ですが、問題に与えられた条件では「ファイルから1行ずつ読み込み」とありますよね。この「読み込み」の部分に引っかりを感じました。Ruby に限ったことではありませんが、ワンライナーの場合、そもそも「読み込み」の部分が記述されいなことになります。ワンライナーの場合は「読み込み」ではなく、「処理」が1行ずつされることが保証されているだけですよね。。。。
実行するとfile.txtは書き換わってしまうので注意
1 | vim -c "%g/^#/d _|wq" file.txt
|
細かい点ですが、問題に与えられた条件では「ファイルから1行ずつ読み込み」とありますよね。この「読み込み」の部分に引っかりを感じました。Vimに限ったことではありませんが、ワンライナーの場合、そもそも「読み込み」の部分が記述されいなことになります。ワンライナーの場合は「読み込み」ではなく、「処理」が1行ずつされることが保証されているだけですよね。。。。
ワンライナーです。
1 | ruby -pe "next if /^#/"
|
1 2 | import fileinput
map(open("out.txt", "w").write, filter(lambda v: not v.startswith("#"), fileinput.input()))
|
Script系はさすがに短いなぁ… closeしてないけどreaderだから許して?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import java.io.*;
public class RemoveLine {
public static void main(String args[]) {
if (args.length < 1) return;
try {
BufferedReader reader = new BufferedReader(new FileReader(args[0]));
String line = reader.readLine();
while (line != null) {
if (!line.startsWith("#"))
System.out.println(line);
line = reader.readLine();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
|
久々にC言語。エラー処理をたくさん書かないといけなかったのがC言語なんだよな。Perlはor dieですむから困る。
……すんません、ろくに例外処理してません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <stdio.h>
#include <stdlib.h>
#define MAXLENGTH 80
int main( int argc, char *argv[] )
{
FILE *fh_input;
FILE *fh_output;
char line[MAXLENGTH];
if ( argc != 3 ) {
printf( "%s <input> <output>\n", argv[0] );
exit(1);
}
fh_input = fopen( argv[1], "r" );
if( fh_input == NULL ) {
printf( "%s: file open error!\n", argv[1] );
exit(1);
}
fh_output = fopen( argv[2], "w" );
if( fh_output == NULL ) {
printf( "%s: file open error!\n", argv[2] );
exit(1);
}
while( fgets( line, MAXLENGTH, fh_input ) != NULL ) {
if( line[0] != '#' ) {
fputs( line, fh_output );
}
}
fclose( fh_output );
fclose( fh_input );
exit(0);
}
|
「Perlはor dieですむ」。。。C言語でも、die 関数定義すれば、いいのでは? 整数型として定義して、va_list, va_start, va_end なんか使えば、とっても面倒くさいけど、定義できますよ。いちど die 定義すれば便利につかえますから、やってみてもいいかもですね。
http://homepage2.nifty.com/mattsan/software/samples/sample034.html
PHP4以下なら普通にfopenとかで
1 2 3 4 5 6 7 8 9 10 | <?php
function removeComment($infile, $outfile, $startwith ='#') {
$r = "";
foreach(file($infile) as $line) {
if (strncmp($line, $startwith, strlen($startwith))) {
$r .= $line;
}
}
file_put_contents($outfile, $r);
}
|
1 | main = getContents >>= putStr . unlines . filter (('#' /=) . head) . lines
|
空行に対応していなかったので書き直し
1 2 3 4 | main = getContents >>= mapM_ putStrLn' . lines
putStrLn' ('#':_) = return ()
putStrLn' xs = putStrLn xs
|
ファイルの入出力はリダイレクションを利用。 Pythonのリストは遅延評価しないので、その場で評価され中身が実行される。
1 2 | import sys
[l.startswith('#') or sys.stdout.write(l) for l in sys.stdin]
|
すでにほとんど同じものがありますが :)
1 2 3 4 5 6 | module Main (main) where
main :: IO ()
main = putStr . unlines . filter (null ||| ('#'/=) . head) . lines =<< getContents
infixr 2 |||
(|||) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
(p ||| q) x = if p x then True else q x
|
lambdaがいやだったので、any-predなんぞを使ってみました。
1 2 | #!/usr/local/bin/gosh
(port-for-each (any-pred #/^#/ print) read-line)
|
この発想はなかった。
コマンドラインオプションなしで
1 | gets$9;gsub /^#.+$/,""
|
出力しなよ!
awk '!/^#/ {print}' ./data.txt > ./data2.txt
1 | !/^[^#]/ {print;}
|
コピペミス
1 | !/^#/ {print}
|
{print} なしでもいけるはず。。。
1 | awk '!/^#/'
|
細かい点ですが、問題に与えられた条件では「ファイルから1行ずつ読み込み」とありますよね。この「読み込み」の部分に引っかりを感じました。AWK に限ったことではありませんが、ワンライナーの場合、そもそも「読み込み」の部分が記述されいなことになります。ワンライナーの場合は「読み込み」ではなく、「処理」が1行ずつされることが保証されているだけですよね。。。。(っと、自分の出した投稿に対して、後から突っ込みいれたりして。。。)
これはひどい
1 2 3 4 5 6 7 8 9 10 11 | <?php
$handle = fopen('hoge.txt','r');
while(!feof($handle)){
$buffer = fgets($handle);
if(substr($buffer,0,1) != '#'){
$array[] = $buffer;
}
}
fclose($handle);
file_put_contents('hoge.txt',$array)
?>
|
使用例: (erase-commen-out-line 入力ファイル 出力ファイル)
1 2 3 4 5 6 7 8 9 | (defun erase-comment-out-line (infile outfile)
(with-open-file (in infile :direction :input)
(with-open-file (out outfile :direction :output
:if-exists :supersede)
(do ((line (read-line in nil 'eof)
(read-line in nil 'eof)))
((eql line 'eof) 'Done)
(unless (equal (schar line 0) #\#)
(write-line line out))))))
|
正規表現でやろうとしたけど、うまくいかなかった。
行頭を拾うのってどうすればいいんだっけ?
1 2 3 4 5 6 7 8 9 10 11 12 13 | # -*- coding: utf-8 -*-
infile = open("intext.txt", "r")
s = infile.read()
infile.close()
outfile = open("outtext.txt", "w")
for x in s.splitlines():
if x[0] != "#":
outfile.write(x + "\n")
outfile.close()
|
行頭は^。
処理の中身を想像すると、正規表現内で否定を拾うより、ifの否定でやったほうが効率が良い気がする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # -*- coding: utf-8 -*-
import re
infile = open("intext.txt", "r")
s = infile.read()
infile.close()
outfile = open("outtext.txt", "w")
for x in s.splitlines():
if re.compile("^[^#]").search(x):
outfile.write(x + "\n")
outfile.close()
|
なんでマイナス評価付いてるんだろう~ と思ったけど、プラス評価するほどでもないので評価はスルーで。 ・readしてsplitしなくてもfileオブジェクトはイテレータ ・正規表現のコンパイルは重い処理なのでループの外へ 頭にシャープがあるかないかだけだから 正規表現を使うまでもない気もするけれど。
1 2 3 4 5 6 7 8 9 10 11 12 | import re
infile = file("tmp.txt")
outfile = file("tmpout.txt", "w")
pat = re.compile("^[^#]")
for line in infile:
if pat.match(line):
outfile.write(line)
infile.close()
outfile.close()
|
ゆるせるワンライナー。 ・ジェネレーター内包表現でコメント行を捨てる ・ファイルを変数に代入しないのでcloseはGC時に自動的に
1 2 3 4 5 | file("tmpout.txt", "w").write(
"".join(
line
for line in file("tmp.txt")
if line[0] != "#"))
|
ゆるせないワンライナー ・リスト内包表現で副作用のある関数を呼ぶのは嫌い ・素直にfor文で書いた方がいい
1 2 3 | [file("tmpout.txt", "w").write(line)
for line in file("tmp.txt")
if line[0] != "#")]
|
1 2 3 4 5 6 7 8 9 10 | using System;
class Program
{
static void Main()
{
string s;
while ((s = Console.ReadLine()) != null)
if (!s.StartsWith("#")) Console.WriteLine(s);
}
}
|
grep はないの? grep -v '^#' のほうが美しいと思うけど。
1 | sed '/^#/d' file >file2
|
grepが言語なのかどうかが怪しいですよね (sedが言語なのかどうかもかなり怪しいですけど、 sedスクリプトの存在とチューリング完全であるところから、 まぁ、言語に位置づけてもよいかな、と。) 言語一覧にない言語は「Other」を選んで タグで「grep」などとつけて投稿してもOKですよ この場合は言語「Bash」を選ぶという手もあるかと思いますが。
何気にwith文。多分Python2.5以降限定。
1 2 3 4 5 6 7 8 9 10 11 | from __future__ import with_statement
import sys
def convert(input, output):
with open(output, "w") as io:
for line in open(input):
if not line.startswith("#"):
io.write(line)
if __name__ == '__main__':
convert(sys.argv[1], sys.argv[2])
|
何の変哲もないですが・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <iostream>
#include <fstream>
void convert(const char* input, const char* output)
{
std::ifstream fin(input);
if (fin)
{
std::ofstream fout(output);
std::string s;
while (std::getline(fin, s))
{
if (s.empty() || s[0] != '#')
{
fout << s << std::endl;
}
}
}
}
int main(int argc, char* argv[])
{
if (argc != 3)
{
std::cerr << "usage: input output" << std::endl;
return -1;
}
convert(argv[1], argv[2]);
return 0;
}
|
前投稿したのがあまり面白くなかったので、自前で行分解するイテレータを作ってSTLしてみました。(行数かさばってすみません(汗))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <iterator>
#include <functional>
class line_iterator : public std::iterator<std::input_iterator_tag, std::string>
{
std::istream* _in;
std::string _line;
void getline()
{
if (_in && !std::getline(*_in, _line))
{
_in = NULL;
}
}
public:
explicit line_iterator(std::istream& in) : _in(&in) { getline(); }
line_iterator() : _in(NULL) {}
const std::string& operator*() const { return _line; }
line_iterator& operator++()
{
getline(); return *this;
}
line_iterator operator++(int)
{
line_iterator tmp = *this; getline(); return tmp;
}
friend bool operator==(const line_iterator& lhs, const line_iterator& rhs)
{
return lhs._in == rhs._in;
}
friend bool operator!=(const line_iterator& lhs, const line_iterator& rhs)
{
return lhs._in != rhs._in;
}
};
struct starts_with_sharp : std::unary_function<std::string, bool>
{
bool operator()(const std::string& s) const
{
return !s.empty() && s[0] == '#';
}
};
int main(int argc, char* argv[])
{
if (argc != 3)
{
std::cerr << "usage: input output" << std::endl;
return -1;
}
std::ifstream fin(argv[1]);
std::ofstream fout(argv[2]);
std::remove_copy_if(
line_iterator(fin),
line_iterator(),
std::ostream_iterator<std::string>(fout, "\n"),
starts_with_sharp()
);
return 0;
}
|
Common Lispで初めてfile入出力書いてみたw
1 2 3 4 5 6 7 8 9 10 11 12 13 | (require :iterate)
(in-package :iter)
(defun remove-comments (in out)
(iter (for line in-stream in using #'read-line)
(unless (char= (aref line 0) #\#)
(write-line line out))))
(defun test ()
(with-open-file (in "10.input" :direction :input)
(with-open-file (out "10.output" :direction :output :if-exists :supersede)
(remove-comments in out))))
(test)
|
stream_get_lineバージョン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php
$handle = fopen("odai10.txt", "r");
while(!feof($handle))
{
$buffer = stream_get_line($handle, 4096, "\n");
if(strpos($buffer, "#") !== 0 )
{
$array[] = $buffer;
}
}
fclose($handle);
file_put_contents("odai10.txt", implode("\n", $array));
?>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | my $tmp = <<"EOM";
hello!
# remove this
# don't remove this
bye!
EOM
open(OUT,">output");
for(grep {!/^#/} split /\n/,$tmp){
print OUT "$_\n"
}
close(OUT);
|





にしお
#3366()
Rating0/0=0.00
サンプル入力
サンプル出力[ reply ]