첫 번째 줄에 특정 문자열 조합이 포함된 파일을 반복적으로 검색합니다.

첫 번째 줄에 특정 문자열 조합이 포함된 파일을 반복적으로 검색합니다.

첫 번째 줄에 "StockID" 및 "SellPrice"라는 문자열이 포함된 모든 파일을 찾아야 합니다.

다음은 몇 가지 파일 예입니다.

1.csv:

StockID Dept    Cat2    Cat4    Cat5    Cat6    Cat1    Cat3    Title   Notes   Active  Weight  Sizestr Colorstr    Quantity    Newprice    StockCode   DateAdded   SellPrice   PhotoQuant  PhotoStatus Description stockcontrl Agerestricted
<blank> 1   0   0   0   0   22  0   RAF Air Crew Oxygen Connector   50801   1   150 <blank> <blank> 0   0   50866   2018-09-11 05:54:03 65  5   1   <br />\r\nA wartime RAF aircrew oxygen hose connector.<br />\r\n<br />\r\nAir Ministry stamped with Ref. No. 6D/482, Mk IVA.<br />\r\n<br />\r\nBrass spring loaded top bayonet fitting for the 'walk around' oxygen bottle extension hose (see last photo).<br />\r\n<br />\r\nIn a good condition.    2   0
<blank> 1   0   0   0   0   15  0   WW2 US Airforce Type Handheld Microphone    50619   1   300 <blank> <blank> 1   0   50691   2017-12-06 09:02:11 20  9   1   <br />\r\nWW2 US Airforce Handheld Microphone type NAF 213264-6 and sprung mounting Bracket No. 213264-2.<br />\r\n<br />\r\nType RS 38-A.<br />\r\n<br />\r\nMade by Telephonics Corp.<br />\r\n<br />\r\nIn a un-issued condition.    3   0
<blank> 1   0   0   0   0   22  0   RAF Seat Type Parachute Harness <blank> 1   4500    <blank> <blank> 1   0   50367   2016-11-04 12:02:26 155 8   1   <br />\r\nPost War RAF Pilot Seat Type Parachute Harness.<br />\r\n<br />\r\nThis Irvin manufactured harness is 'new old' stock and is unissued.<br />\r\n<br />\r\nThe label states Irvin Harness type C, Mk10, date 1976.<br />\r\nIt has Irvin marked buckles and complete harness straps all in 'mint' condition.<br />\r\n<br />\r\nFully working Irvin Quick Release Box and a canopy release Irvin  'D-Ring' Handle.<br />\r\n<br />\r\nThis harness is the same style type as the WW2 pattern seat type, and with some work could be made to look like one.<br />\r\n<br />\r\nIdeal for the re-enactor or collector (Not sold for parachuting).<br />\r\n<br />\r\nTotal weight of 4500 gms.   3   0

2.csv:

id  user_id organization_id hash    name    email   date    first_name  hear_about
1   2   15  <blank> Fairley [email protected] 1129889679  John    0

첫 번째 행에 "StockID" 및 "SellPrice"가 포함된 파일만 찾고 싶습니다. 따라서 이 예에서는 ./1.csv만 출력하려고 합니다.

나는 이것을 할 수 있었지만 지금은 막혔습니다 ;(

where=$(find "./backup -type f)
for x in $where; do
   head -1 $x | grep -w "StockID"
done

답변1

find+awk해결책:

find ./backup -type f -exec \
awk 'NR == 1{ if (/StockID.*SellPrice/) print FILENAME; exit }' {} \;

키워드의 순서가 다를 수 있는 경우 패턴을 /StockID.*SellPrice/로 대체합니다 /StockID/ && /SellPrice/.


파일 수가 많은 경우 더 효율적인 대안은 다음과 같습니다(한 번에 여러 파일을 처리합니다. 명령에 대한 총 호출 수는 일치하는 파일 수보다 훨씬 적습니다).

find ./backup -type f -exec \
awk 'FNR == 1 && /StockID.*SellPrice/{ print FILENAME }{ nextfile }' {} +

답변2

GNU grep또는 호환 제품을 사용하세요.

grep -Hrnm1 '^' ./backup | sed -n '/StockID.*SellPrice/s/:1:.*//p'

재귀 grep은 각 파일의 첫 번째 줄을 인쇄하고 인쇄합니다.filename:1:line 아니요전체 파일을 읽고(이 -m1플래그를 사용하면 첫 번째 일치 시 파일이 종료되어야 함) 해당 섹션이 패턴과 일치하는 위치 sed가 인쇄됩니다 .filenameline

실패하고 파일이 표시됩니다.이름여기에는 자체 또는 개행 문자가 포함되어 있지만 각 파일에 대해 다른 프로세스를 수행하는 느린 + 조합을 :1:추가하는 것보다 감수할 가치가 있는 위험입니다 .findawk

답변3

파일당 하나의 명령을 실행하고 전체 파일을 읽는 것을 방지하려면 GNU를 사용하십시오 awk.

(unset -v POSIXLY_CORRECT; exec find backup/ -type f -exec gawk '
  /\<StockID\>/ && /\<SellPrice\>/ {print FILENAME}; {nextfile}' {} +)

또는 다음을 사용하여 zsh:

set -o rematchpcre # where we know for sure \b is supported
for file (backup/**/*(ND.)) {
  IFS= read -r line < $file &&
   [[ $line =~ "\bStockID\b" ]] &&
   [[ $line =~ "\bSellPrice\b" ]] &&
   print -r $file
}

또는:

set -o rematchpcre
print -rl backup/**/*(D.e:'
  IFS= read -r line < $REPLY &&
   [[ $line =~ "\bStockID\b" ]] &&
   [[ $line =~ "\bSellPrice\b" ]]':)

또는 기본 확장 정규식을 지원하는 시스템에서는 단어 경계 연산자 bash(다른 시스템에서는 / 또는 를 시도해 볼 수도 있음):\<\>[[:<:]][[:>:]]\b

RE1='\<StockId\>' RE2='\<SellPrice\>' find backup -type f -exec bash -c '
  for file do
    IFS= read -r line < "$file" &&
    [[ $line =~ $RE1 ]] &&
    [[ $line =~ $RE2 ]] &&
    printf "%s\n" "$file"
  done' bash {} +

답변4

egrep+ awk:

 egrep -Hrn 'StockID|SellPrice' ./backup | awk -F ':' '$2==1{print $1}'

관련 정보