複数のテキストファイルに同じsedコマンドを適用する

複数のテキストファイルに同じsedコマンドを適用する

ファイルの前処理を行っています。次の形式のデータを含むテキストファイルが2つあります。

テキストファイル1

"Name","Age","Class"
"Total Students:","247"
"John","14","8"
"Sara","13","8"

テキストファイル2

"Name","Age","Class"
"Total Students:","119"
"John","15","9"
"Sara","16","9"

私が望むのは、このファイルと引用符から最初の2行を削除してから、次のコマンドを使用してファイルを出力ディレクトリに移動することです。

sed '1d' "$file" >> temp.txt
sed -i '1d' temp.txt
sed -i 's/"//g' temp.txt

mv temp.txt output/$file

私が直面している問題は、これらのコマンドが単一のファイルでのみ機能することです。ファイル名はclass_8.txtそしてclass_9.txt。両方のファイルに同じコマンドを適用する解決策はありますか?元のファイルは保持し、処理されたファイルを出力フォルダに移動したいと思います。

答え1

sed複数のファイルで便利に実行し、同時に複数のファイルに書き込むことはできません(入力と出力が別々のファイルである必要がある場合)。非標準の拡張子を使用するか、式に出力ファイル名をハードコードして使用できますsed

tail操作は非常に簡単ですが、ループでandを使用したい場合があります。tr

for file in Class_{8,9}.txt; do
    tail -n +3 "$file" | tr -d '"' >output/"$file"
done

または本当にsed使用したい場合

for file in Class_{8,9}.txt; do
    sed -e '1,2d' -e 's/"//g' "$file" >output/"$file"
done

ファイルを最初にコピーしてから、コピーに対してsed一度に内部編集を実行することもできます。ある意味、これはループをGNUの内部タスクに委任しますsed

cp Class_{8,9}.txt output
sed -i -e '1,2d' -e 's/"//g' output/Class_{8,9}.txt

フィールドにカンマまたは改行が含まれている場合は、二重引用符を削除すると無効なCSV出力が生成されます。不要な二重引用符のみを削除するには、csvformat次のCSVパーサーを使用してください。csvkit

上記のコマンドはすべて、このoutputディレクトリがファイルを作成できる既存のディレクトリであると仮定しています。

答え2

同じコマンドで別のファイルに書き込むには、コマンドを使用するか、コマンドのフラグをsed使用できます。wws

あなたの場合、行の最後のフィールドはどのファイルに書き込むべきかを決定するクラスフィールドであるようです。最初の2行は有効なクラスがないので無視できるので、気にする必要さえありません。

sed -ne 's/"//g;/,8$/woutput/Class_8.txt' -e '/,9$/woutput/Class_9.txt' file*

したがって、すべての行に対して二重引用符を削除し、作成する必要があるs/"//g最後のフィールドのすべての行を/,8$/選択します。 9レベルも同じだ。このオプションはデフォルト出力を抑制します。8woutput/Class_8.txt-n

もちろん、これは大量のファイルに対して拡張可能ではありません。

答え3

-i.sufsed古いファイルに追加し.suf、変更を新しいファイルに書き込みます。したがって、1)sedファイルを変更し、古いファイルのサフィックスを保持し、2)新しいファイルを移動し、3)サフィックスを削除して、古いファイルの名前を元の名前に変更できます。

sed -i.bup '1,2d;s/"//g' file1.txt file2.txt file3.txt
mv file{1..3}.txt output
rename 's/.bup$//' file{1..3}.txt.bup

rename時々呼び出されるか、prenameディストリビューションperl-renameによって異なります)

答え4

これは両方のファイルを編集し、outputファイル名は同じですが、編集したバージョンのディレクトリに出力をリダイレクトしたい場合にawk機能します。

$ awk 'FNR > 1 { gsub(/\"/,""); print > "output/"FILENAME ; next } FNR > 1 { gsub(/\"/,""); print > "output/"FILENAME }' Class_8.txt Class_9.txt

またはスクリプトとして

$ cat awk.script

FNR > 1 {                      #Remove line 1 from first file
    gsub(/\"/,"")              #Substitute all double quotes for nothing
    print > "output/"FILENAME  #Send the output to new directory with the same filename
    next                       #Move on to the next file
} FNR > 1 {                    #Remove line 1 from second file
    gsub(/\"/,"")              #Substitute all double quotes for nothing
    print > "output/"FILENAME  #Send the output to new directory with the same filename
}

ファイルでスクリプトを使用するには、次のコマンドを実行できます。

$ awk -f awk.script Class_8.txt Class_9.txt

出力は次のとおりです

$ cat output/Class_8.txt
Total Students:,247
John,14,8
Sara,13,8
$ cat output/Class_9.txt
Total Students:,119
John,15,9
Sara,16,9

関連情報