하위 폴더가 포함된 폴더에 있는 모든 txt 파일의 첫 번째 줄을 읽고 파일 이름과 첫 번째 줄을 다른 파일에 인쇄합니다.

하위 폴더가 포함된 폴더에 있는 모든 txt 파일의 첫 번째 줄을 읽고 파일 이름과 첫 번째 줄을 다른 파일에 인쇄합니다.

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 {} \;

빈 파일과 공백이 포함된 파일 이름도 처리됩니다. basenameMacOS 사용자는 사용 하지 못할 수 있습니다 .

답변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/\([^/]*/\)*||' 

관련 정보