4つのファイルがあります。すべてのファイルの行数が同じであることを確認する必要があります。
行数が異なる場合は、それを検出して出力する必要があります。たとえば、次のようになります。
#file1 - 10 lines, file2 - 9 lines, file3 - 10 lines, file4 - 10 lines
Line are miss matched
Number of lines 10 = 9 = 10 = 10
同じ場合は、次のようにファイルを1行ずつマージしたいと思います。
文書:
#file1
10
12
11
#file2
Arun
kamal
babu
#file3
300
200
400
#file4
spot1
spot4
spot5
出力:
Set1
10
Arun
300
spot1
Set2
12
kamal
200
spot4
Set3
11
babu
400
spot5
私のコード:
#
id_name=`cat file2`
echo $id_name
id_list=`cat file1`
echo $id_list
#
id_count=`cat file3`
echo $id_count
id_spot=`cat spot_list`
echo $id_spot
SS=`cat id_list | wc -l`
DS=`cat id_name | wc -l`
SF=`cat id_count | wc -l`
DF=`cat id_spot | wc -l`
if [ $SS == $DS == $SF == $DF ] then
echo " Line are matched"
echo " Total line $SS"
for i j in $id_list $id_name
do
for a b in $id_count $id_spot
do
k = 1
echo " Set$k"
$i
$j
$a
$b
done
done
else
echo " Line are Miss matched"
echo " Total line $SS = $DS = $SF = $DF"
fi
答え1
非常に簡単な方法で:
#!/usr/bin/env bash
SS=$(wc -l < file1)
DS=$(wc -l < file2)
SF=$(wc -l < file3)
DF=$(wc -l < file4)
if [[ $SS -eq $DS && $DS -eq $SF && $SF -eq $DF ]]; then
echo "Lines are matched"
echo "Total number of lines: $SS"
num=1
while (( num <= SS )); do
echo "Set$num"
tail -n +$num file1 | head -n 1
tail -n +$num file2 | head -n 1
tail -n +$num file3 | head -n 1
tail -n +$num file4 | head -n 1
((num++))
echo
done
else
echo "Line are miss matched"
echo "Number of lines $SS = $DS = $SF = $DF"
fi
4*number_of_lines 回呼び出すので、それほど効率的ではありませんがtail
簡単です。
while
もう一つの方法はループを次に置き換えることですawk
。
awk '{
printf("\nSet%s\n", NR)
print;
if( getline < "file2" )
print
if( getline < "file3" )
print
if ( getline < "file4" )
print
}' file1
このコマンドは、ファイルを1行ずつリンクするのにpaste
役立ちます。ループの代わりにこれを使用できますwhile
。
paste -d$'\n' file1 file2 file3 file4
またはそれほど明確ではないかもしれません。
{ cat -n file1 ; cat -n file2 ; cat -n file3; cat -n file4; } | sort -n | cut -f2-
これにより行が出力されますが、書式は指定されません(Set1、Set2、改行などはありません)。awk
たとえば、次のように書式設定する必要があります。
awk '{
if ((NR-1)%4 == 0)
printf("\nSet%s\n", (NR+3)/4)
print
}' < <(paste -d$'\n' file1 file2 file3 file4)
いくつかの最終注意事項:
- 環境および内部シェル変数と競合する可能性があるため、大文字変数を使用しないでください。
- 入力をリダイレクトできる場合、またはを使用しないでください
echo "$var" | cmd
。またはcat file | cmd
cmd <<< "$var"
cmd < file
for
ループには変数名が1つしかありません。for i in ...
有効、そうでなければfor i j in ...
無効[[ ]]
テストするよりも使用する方が良いです[ ]
。これを参照してください回答- 一つあるたくさんこれを行う方法
- 使用方法を選択できますが、効率の違いに注意してください。
time
10,000行のファイルでテストした結果:
#first approach
real 0m45.387s
user 0m5.904s
sys 0m3.836s
#second approach - significantly faster
real 0m0.086s
user 0m0.024s
sys 0m0.040s
#third approach - very close to second approach
real 0m0.074s
user 0m0.016s
sys 0m0.036s
答え2
ファイルごとの行数を確認する方法がわかります。 (ヒントwc
:)
コレクションの出力を取得するには:
paste File{1,2,3,4} | awk -F'\t' -v OFS='\n' '{$1=$1; print "Set"NR, $0, ""}'
$1=$1
入力フィールド区切り記号を出力フィールド区切り文字に変換するために使用されます。