grep 파일의 시작?


10

리눅스 셸에서 특정 파일 세트가 모두 시작으로 <?끝나고 정확한 문자열이 있고 다른 문자는 시작하지 않도록하고 싶습니다 . "파일 시작"을 표현하기 위해 어떻게 grep하거나 다른 것을 사용할 수 있습니까?


편집 : 나는 이것을 와일드 카드 head로 만들고 같은 줄에 파일 이름을 지정하지 않으므로 grep 할 때 파일 이름이 표시되지 않습니다. 또한 "^<?"올바른 결과를 제공하지 않는 것 같습니다. 기본적으로 나는 이것을 얻고있다 :

$> head -1 * | grep "^<?"
<?
<?
<?
<?
<?
...

모든 파일이 실제로 좋습니다.

답변:


11

배쉬에서 :

for file in *; do [[ "$(head -1 "$file")" =~ ^\<\? ]] || echo "$file"; done

파일인지 확인하십시오.

for file in *; do [ -f "$file" ] || continue; [[ "$(head -1 "$file")" =~ ^\<\? ]] || echo "$file"; done


그리고 우리 모두가 너무 놀랍기 때문에 : 대량의 파일 이름에 glob 연산자를 사용하지 말고 대신 사용하십시오find
akira

를 사용 find하면 일반 파일 만 직접 반환하여 파이프를 시작할 수 있습니다.
mpez0

1
를 사용하는 read대신 Bash에서 완전히 수행 할 수도 head있습니다. for file in *; do [ -f "$file" ] || continue; read < "$file"; [[ "$REPLY" =~ ^\<\? ]] || echo "$file"; done
janmoesen

4

grep:

$ head -n 1 * | grep -B1 "^<?"
==> foo <==
<?
--
==> bar <==
<?
--
==> baz <==
<?

파일 이름을 구문 분석하십시오.

$ head -n 1 * | grep -B1 "^<?" | sed -n 's/^==> \(.*\) <==$/\1/p'
foo
bar
baz

3

이것을 위해 awk를 사용할 수 있습니다 :

$ cat test1
<?xxx>
111
222
333
$ cat test2
qqq
aaa
zzz
$ awk '/^<\?/{print "Starting with \"<?\":\t" ARGV[ARGIND]; nextfile} {print "Not starting with \"<?\":\t" ARGV[ARGIND]; nextfile}' *
Starting with "<?":     test1
Not starting with "<?": test2
$

3

빈 파일을 제외하고이 Perl 스크립트는 작동하는 것 같습니다.

perl -e 'while (<>) { print "$ARGV\n" unless m/^<\?/; close ARGV; }' *

빈 파일을 처리하는 방법을 즉시 잘 모르겠습니다. 나는 그것들을 별도의 특별한 경우로 취급하고 싶습니다.

find . -type f -size +0 -print0 |
    xargs -0 perl -e 'while (<>) { print "$ARGV\n" unless m/^<\?/; close ARGV; }'

2

이 시도

for i in `find * | grep "php$"`; do echo -n $i " -> "; head -1 $i; done

PHP로 끝나는 모든 파일의 목록을 얻은 다음 루프를 통해 루프합니다. 파일 이름을 반영한 다음 파일의 첫 번째 줄을 인쇄합니다. 방금 삽입

다음과 같은 출력을 제공합니다.

calendar.php  -> <?php
error.php  -> <?php
events.php  -> <?php
gallery.php  ->
index.php  -> <?php
splash.php  -> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
information.php  -> <?php
location.php  -> <?php
menu.php  -> <?php
res.php  -> <?php
blah.php  -> <?php

그런 다음 끝에 일반 grep을 붙여보고 싶은 것을 제거하고 예외를 찾을 수 있습니다.

for i in `find * | grep "php$"`; do echo -n $i " -> "; head -1 $i; done | grep -v "<?php"

산출:

gallery.php  ->
splash.php  -> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

4
쓸데없는 grep 사용; "find -name '* .php'"를 사용하십시오. 또한 변수의 위험한 사용 : "특별한"파일 이름 문제를 피하려면 "find -exec 명령을 여기에 '{}' '+'"를 사용하십시오. 그 외에도 항상 "head -1 $ i"가 ​​아니라 "head -1"$ i ""라는 변수를 인용하십시오.
janmoesen

for x in *.php;do echo $x \"head -n1 $ x\";done
user23307

1

배쉬 4.0

#!/bin/bash
shopt -s globstar
for php file in /path/**/*.php
do
   exec 4<"$php";read line <&4;exec 4<&-
   case "$line" in
     "<?"*) echo "found: $php"
   esac

done

0
cat file.txt | head -1 | grep "^<?"

당신이 원하는 것을해야합니다.


예, 그러나 와일드 카드를 사용하면 파일 이름을 제공하지 않습니다. "또한"^ <? "가 작동하지 않으면 -v 스위치를 사용했습니다.
user13743

2
@Phoshi 강제 cat사용 head -1 file.txt | grep "^<?"으로 충분합니다.
Benjamin Bannier

1
고양이의 쓸모없는 사용 :-(((
vwegert

쓸모없는 고양이는 쓸모가 없다 :(
user13743

모든 것을 모듈화하고 세분화하면 명령을 기억하는 것이 훨씬 간단하다는 것을 알았습니다. 나는 고양이가 작동 할 command것이고, 파일을 인수로 취할 것인지 모르겠다 . 꼭 필요한 것은 아니지만, 나는 그것을 꺼내지 않을 것이다 :)
Phoshi

0

이:

  % for i in *; do head -1 $i | grep "^<?" ; echo "$i : $?"; done

다음과 같은 것을 제공합니다.

  foo.xml: 0
  bla.txt: 1

패턴을 포함하지 않는 모든 파일은 "1"로 "표시"됩니다. 당신의 요구에 맞을 때까지 그것을 가지고 놀 수 있습니다.


1
파일 이름에 공백이 있으면 파일 이름을 인용해야합니다. 그리고 아마도 'grep'에서 / dev / null로 출력을 잃고 싶을 것입니다. 당신은 또한 사용할 수 있습니다 : head -1 "$i" | grep '^<?' || echo "$i"문제가있는 경우에만 파일 이름을 인쇄합니다.
Jonathan Leffler

2
이것이 바로 "grep -q"입니다. :-)
janmoesen

0

이것에 가자

찾기 유형 f | awk '
{
 if (getline ret <$ 0) {
  if (ret ~ "^ <\\? $") {
   print "Good ["$ 0 "] ["ret "]";
  }그밖에{
   "실패 ["$ 0 "]"인쇄;
  };
 }그밖에{
  "empty ["$ 0 "]"인쇄;
 };
 닫기 ($ 0);
} '

아무도 왁스를 사용할 수 없다고 말했다 :-)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.