Ubuntu 시스템에서 약 20,000개의 txt 파일을 읽고 다음과 같이 각 파일의 첫 번째 줄을 새 txt 파일에 삽입해야 합니다.
Filename1.txt | FirstLineoftheFilename1.txt
Filename2.txt | FirstLineoftheFilename2.txt
Filename3.txt | FirstLineoftheFilename3.txt
sed
명령을 시도했는데 첫 번째 줄을 인쇄할 수 있습니다.
다음 find
명령은 올바른 파일을 식별합니다.
find /db/users/logs/ -name '*.txt' -exec sed -n '1p' {} \; -exec basename {} \;
하지만 출력을 한 줄로 결합하고 인쇄하는 방법을 모르겠습니다 find
.sed
도움이 필요하세요?
미리 감사드립니다!
답변1
GNU를 사용할 수 있습니다 awk
.
LC_ALL=C find /db/users/logs/ -name '*.txt' -type f -exec gawk '{
f = FILENAME; sub(".*/", "", f)
print f" | "$0; nextfile}' {} +
또는 perl
:
LC_ALL=C find . -type f -name '*.txt' -exec perl -lne '
print $ARGV =~ s:.*/::r . " | $_"; close ARGV' {} +
또는 쉘:
LC_ALL=C find /db/users/logs/ -type f -name '*.txt' -exec sh -c '
for file do
<"$file" IFS= read -r line || [ -n "$line" ] &&
printf "%s\n" "${file##*/} | $line"
done' sh {} +
sh
(이 방법은 첫 번째 줄에 NUL 문자가 포함된 경우 대부분의 구현에서 제대로 작동하지 않습니다.텍스트문서).
답변2
또 다른 변형이 있습니다:
$ find /db/users/logs/ -type f -name "*.txt" -exec \
sh -c 'printf "%s | %s\n" "$(basename $1)" "$(head -1 $1)"' shellproc {} \;
빈 파일과 공백이 포함된 파일 이름도 처리됩니다. basename
MacOS 사용자는 사용 하지 못할 수 있습니다 .
답변3
방법-a)
find /db/users/logs -type f -name '*.txt' \
! -empty -printf '%f | ' \
-exec head -n 1 \{\} \;
find
방법 ii) Perl 모듈 File::Find를 사용하여 명령의 기능을 캡슐화합니다.
perl -MFile::Find -e '
find( sub { my $fh;
-f && ! -z && /\.txt$/ and
open($fh, "<", $_) and
print("$_ | " . <$fh>) },
shift )
' /db/users/logs
기본 이름의 필요성을 지적한 Stephane에게 감사드립니다. 파일 이름에 개행 문자가 없는 경우에도 이 작업을 수행할 수 있으며 파이프 대신 콜론을 구분 기호로 사용할 수 있습니다.
$ find /db/users/logs/ \
-type f -name '*.txt' \
-exec grep -Hm1 "^" {} + |
sed 's|^/db/users/logs/\([^/]*/\)*||'