몇 가지 파일이 있습니다.
file1.csv
file2.csv
file3.csv
주어진 스크립트는 이를 처리하고 다음 파일에 기록합니다.
my.log
다음 형식을 취하세요: ( filename
col2
col3
):
file1.csv 1 a
file2.csv 1 a
file3.csv 1 a
file2.csv 2 b
file1.csv 2 b
file3.csv 2 b
file1.csv 3 c
file2.csv 3 c
file3.csv 3 c
file2.csv 4 d
file3.csv 4 d
col3
각 파일 (마지막 파일만) 에 대해 파일에서 값을 얻고 싶습니다 .my.log
*.csv
다음 명령을 실행합니다.
ls *.csv | xargs -I@ bash -c "cat my.log | grep @ | tail -n 1 | awk '{ print $3 }'"
awk가 나에게 모든 열을 제공한다는 점을 제외하면 잘 작동합니다.
file1.csv 3 c
file2.csv 4 d
file3.csv 4 d
열을 하나만 얻으려면 어떻게 해야 합니까 col3
? 예를 들면 다음과 같습니다.
c
d
d
답변1
당신의 표현에
"cat my.log | grep @ | tail -n 1 | awk '{ print $3 }'"
...문자열 주위의 큰따옴표는 작은따옴표가 리터럴로 처리된다는 의미입니다. 쉘을 보호하지 않으므로 $3
환경 변수로 확장됩니다. 실제로 쉘에 의해 정의되지 않았기 때문에 $3
(3개의 인수로 호출하는 스크립트에 있지 않는 한) 빈 문자열이 되고 표현식은 awk
단순히 { print }
전체 줄을 인쇄합니다.
다음을 이스케이프 처리하여 이 문제를 해결할 수 있습니다 $
.
ls *.csv | xargs -I@ bash -c "cat my.log | grep @|tail -n 1|awk '{print \$3}'"
...또는 표현식을 awk
밖으로 이동하여 xargs
:
ls *.csv | xargs -I@ bash -c "cat my.log | grep @|tail -n 1"|awk '{print $3}'
답변2
ls
단순히 터미널에서 보는 것 외에 into 의 출력을 파이프로 연결하는 것은 좋지 않습니다 xargs
(사실, into 의 출력으로 무엇이든 하는 것은 좋지 않습니다 ).ls
나쁜 생각). 꼭 이와 같은 작업을 수행해야 한다면 최소한 그런 작업을 사용 find . -maxdepth 1 -type f -iname '*.csv' -print0
하고 xargs -0r
.
하지만 이 경우에는 .csv 파일의 파일 이름이 다음과 같으므로 전혀 그렇게 할 필요가 없습니다.이미 여기에my.log
.
전혀:
#!/usr/bin/awk -f
{ seen[$1] = $3 }
END {
for (f in seen) { print seen[f] };
}
또는 한 줄로:
$ awk '{seen[$1] = $3}; END {for (f in seen) { print seen[f] };}' my.log
c
d
d
그러면 열 1에 나열된 각 파일에 대해 열 3에 표시된 마지막 값이 인쇄됩니다.
열 3에 표시된 첫 번째 값만 인쇄하려면 다음과 같이 변경하세요.
!seen[$1] { seen[$1] = $3 }
현재 디렉토리에 있는 모든 파일의 파일 이름을 사용하고 싶지 않고 find | xargs
실제로 사용해야 하는 경우 대안은 다음을 수행하는 것입니다..csv
#!/usr/bin/perl
use strict;
my $logfile=shift; # get the first arg (the logfile name)
my $re=join("|",@ARGV); # turn the remaining args into a regular expression
@ARGV=$logfile; # set the logfile name as the sole cmd-line argument.
my %seen=();
while(<>) {
next unless (m/^($re)/o); # ignore any filenames that weren't on the cmd line.
my(@F) = split;
$seen{$F[0]} = $F[2]; # perl arrays start from 0, not 1.
};
foreach my $file (sort keys %seen) {
print $seen{$file}, "\n";
};
예를 들어 다른 이름으로 저장하고 nandro.pl
실행 가능하게 만든 후 chmod +x
다음과 같이 실행합니다.
$ ./nandro.pl my.log *.csv
c
d
d