印刷前のawkテキスト処理

印刷前のawkテキスト処理

私はスクリプトを書くのが好きではありませんが、このフォーラムの助けを借りてスクリプトを作成できました。問題がありますが、正常に動作しません(可能であるかどうかわからない)。

コンテンツを含むファイルがありますY

lrwxrwxrwx  1  user1 gp  35  2021-09-07  2000  /folder/subfolder1/subfolder2/subfolder3/main/summary.txt
lrwxrwxrwx  1  user1 gp  35  2021-09-08  1400  /folder/subfolder1/subfolder2/main/summary.txt
lrwxrwxrwx  1  user1 gp  35  2021-09-09  1800  /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt

以下のように3,6,7,8列を出力し、「main」の前のフォルダ名に関連付けたいと思います。

user1 2021-09-07  2000  /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08  1400  /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09  1800  /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

次の方法はどうすればよいですか?sedコマンドをawkコマンドの{print}変数の1つとして使用しますか?

awk '{print $3,$6,$7,$8}' fileY
sed 's/\// /g; s/\./ /g' fileY | awk '{for(i=8;i<=NF;i++){if($i~/^main/){a=i}} print $(a-1)}'

答え1

awkを使用すると、sedは必要ありません。必要なディレクトリが常にパスの3番目のディレクトリである場合(例のように)、必要なのはawkを使用するだけです。

$ awk '{print $3, $6, $7, $8, p[split($8,p,"/")-2]}' file
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

それ以外の場合は、match()の3番目の引数を使用してGNU awkを使用してください。

$ awk '{match($8,"([^/]+)/main/",a); print $3, $6, $7, $8, a[1]}' file
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

または awk を使用してください。

$ awk '{match($8,"[^/]+/main/"); print $3, $6, $7, $8, substr($8,RSTART,RLENGTH-6)}' file
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

答え2

私はあなたがなぜそこに欲しいのか本当に理解していませんsed。あなたは1つだけで行うことができますawk。もちろん、これはフォルダ名にスペースや改行がなく、スペースをフィールド区切り文字として安全に使用できると仮定します。これが真でない場合は、質問を編集してより包括的な例を追加してください。

$ awk '{ 
            split($8,dirs,"/");
            dir="" 
            for(i in dirs){ 
                if(dirs[i+1]=="main"){
                    dir=dirs[i]
                } 
            } 
            print $3,$6,$7,$8,dir}' fileY
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

ここでの秘密は、8番目のフィールドを区切り文字として使用する配列にsplit()分割することです。次に、次の配列項目が最後の配列項目を繰り返し保持します。これは、複数回発生した場合、最後の項目のみが一致することを意味します。dirs/dirsmainmain

答え3

別のアプローチは、フォルダ名構造が与えられた例()と一致すると仮定し、必要なフォルダrevが区切り文字として逆に使用される3番目の項目であるという事実を利用してを使用することです。/<wanted folder>/main/summary.txt

$ rev file | awk -F'/' '{ print $3,$0 }' | rev | awk '{ print $3,$6,$7,$8,$9 }'
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

答え4

sedGNUネストグループ化の使用

$ sed -E 's|.*\s[0-9]\s\s(.[^ ]*).*([0-9]{4}-.*/(.[^/]*).*/.*/.*)|\1 \2 \3|' input_file
user1 2021-09-07  2000  /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08  1400  /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09  1800  /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

関連情報