
ファイルは入力ファイルを使用してスクリプトによって変更されます。
141、141_1、BAR、HONDA、ps2_0、未割り当て、ps3_0、未割り当て、ps4_0、未割り当て、ps5_0、未割り当て、ps6_0、未割り当て、ps7_3、TILL WILL、.....
入力ファイル-
141,ps7,ティルウィル
ここで、列 ps7_3 が正しい値に更新されているかどうかを検索する必要があります。
そこで入力ファイルから列を分離しました。
while read -r line;
do
sub1=$(echo $line|cut -f 1 -d ',');
sub2=$(echo $line|cut -f 2 -d ',');
sub3=$(echo $line|cut -f 3 -d ',');
sub4=$(echo $sub2'.*,'$sub3|sed -e "s/\(.*\)\r/'\1'/");
echo $sub1;
echo $sub2;
echo $sub3;
echo $sub4;
grep $sub4 modded_file.csv.dat;
done<input.csv
出力は-
141
ps7
TILL WILL
'ps7.*,TILL WILL'
grep: WILL': No such file or directory
しかし、 を実行すると grep 'ps7.*,TILL WILL' modded_file.csv.dat
動作します。ファイル内で上記のような変数を grep するにはどうすればよいでしょうか?
答え1
入力からわかるように、変数 sub4 にスペース記号があるので、この行を書き直してください。
grep $sub4 modded_file.csv.dat;
することが
grep -- "$sub4" modded_file.csv.dat;
(@philippos による追加)
また、一重引用符は検索パターンの一部とみなされるため、$sub4
含めないでください。'
あなたの誤解は、引用符と展開の実行順序だと思います。まず変数が展開され、次に引用符が実行されるので、展開後に変数のシングルクォートが文字列を引用符で囲むと考えています。しかし、実際には引用符は変数展開の前に行われるため、$sub
答え2
grep
ループ内で実行するのは大きなアンチパターンです。代わりにこれを試してください。
awk -F "," 'NR==FNR { key[$1]=$2; value[$1]=$3; next }
($1 in key) && ($0 !~ "^" $1 ",.*," key[$1] "," value[$1] ",")' input.csv modded_file.csv.dat
なぜそこに何かを入れたいのか、または期待しているのか理解しようとはしていない\r
ので、おそらく何らかの調整が必要になるでしょう。
Awkスクリプトは、各入力行に順番に適用される*条件{
アクションのペアのシーケンスで構成されます。を使用して、この入力行の残りのスクリプトをスキップして次の入力にスキップすることができます。}
next
{
アクション}
入力行全体を印刷したい場合は、状態 (無条件に何かを実行したい場合) 各行は、スクリプト内で 、 などとして使用できるフィールドに分割されます。 $1
フィールド区切り文字をコンマに設定します (デフォルトは空白のシーケンスです)。$2
-F ","
このNR==FNR
慣用句は、Awk で 2 つの入力ファイルを処理するための一般的な方法です。最初の入力ファイルを処理しているとき、全体の行番号はNR
ファイル内の行番号と同じになりFNR
、それ以降は false になります。
最初のファイルを読み取るとき、最初のフィールドをキーとする 2 つの連想配列にフィールドを格納します。
2 番目のファイルを読み取るときに、配列内でキーが見つかったすべての入力行を出力しますkey
が、行全体が予想される正規表現と一致しません (最初のフィールドはキーで、その後に任意の文字列が続き、その後にコンマ、 に格納した列名key[$1]
、別のコンマ、 に格納した予想される値value[$1]
、さらに別のコンマが続きます)。
つまり、これは期待された条件が満たされなかった行を見つけます。!
代わりに一致するものが必要な場合は、 を削除します。