
次の形式のテキストファイルがあります。
dir1/sub-dir1/.../filename1 author date
dir1/sub-dir1/.../filename2 author date
.
.
.
dir2/sub-di2/.../filename1 author date
dir2/sub-dir2/.../filename2 author date
追加の詳細:
- リストされた各ファイル名は正確に1〜2回発生します。つまり、
filename_n
正確に1~2回存在します。一度存在する場合、パスに応じてv1またはv2の1つのソフトウェアバージョンにのみ存在します。 2回存在する場合、ファイルはv1とv2の両方です。 - パスによって、ファイルが v1 か v2 かが決まります。
- テキストファイルはタブで区切られます。
- サブディレクトリの数はファイルごとに(したがって
...
コードブロック内で)異なります。 - (作成者と日付はこれから取得されません
ls
。このファイルの変更を記録した最後のgitコミットを要求することによって別々に生成されます。)
sedとregexを使ってファイルを次のように変換してみました。
dir1/sub-dir1/.../filename1 author date dir2/sub-di2/.../filename1 author date
dir1/sub-dir1/.../filename2 author date dir2/sub-dir2/.../filename2 author date
.
.
.
一致するものがない場合は、filename-n
2回ではなく1回だけ表示する必要があります。
sedと正規表現を使用して変換を実行する方法を探しています。同じファイル(使用-i
)に書き込むか、別のファイルに書き込むことができます。
答え1
以下を使用してこれを行うことは完全に可能ですsed
。sed
sort
ファイル名は3番目のサブディレクトリにあり、4番目のフィールド(-k 4
)と\
(一体なぜ!!)をフィールド区切り文字として使用するように指示されます。
sort -t'\' -k 4 /tmp/p|sed 'N;/\(\\[^\]* \).*\1/s/\n/ /;P;D'
このsed
コマンドは通常のN;P;D
ループを使用して、常に一度に2行を処理し、\
ファイル名(TAB間)が重複していることを確認します。
スクリプトには2つのテキストタブがありますsed
。 GNUを使用すると、次のように書くsed
ことができます\t
。
sort -t'\' -k 4 /tmp/p|sed 'N;/\(\\[^\]*\t\).*\1/s/\n/\t/;P;D'
さらに、タブまたはバックスラッシュを含むパスはスクリプトを破損する可能性があります。
答え2
パスに含まれる文字(改行を除く)に関係なく、すべてのUnixシステムのすべてのシェルでawkを使用してください。
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
file = $0
sub(".*/","",file)
paths[file] = (file in paths ? paths[file] OFS : "") $0
}
END {
for ( file in paths ) {
print paths[file]
}
}
$ awk -f tst.awk file
dir1/sub-dir1/.../filename2 author date dir2/sub-dir2/.../filename2 author date
. . .
dir1/sub-dir1/.../filename1 author date dir2/sub-di2/.../filename1 author date
出力順序が重要な場合、これはマイナーな調整です。出力順序が何であるかを教えてください(たとえば、最初に読み取る、ファイル名のアルファベット順、ディレクトリのアルファベット順など)。