grep文件的开头?


10

在linux shell中,我要确保所有特定文件集均以开头<?,并且具有确切的字符串,而没有其他字符。如何grep或使用其他表达“文件开头”的文件?


编辑:我是通配符,并且head没有在同一行上提供文件名,所以当我grep它时,我看不到线名。另外,"^<?"似乎没有给出正确的结果;基本上我得到这个:

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

所有文件实际上都很好。

Answers:


11

在Bash中:

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 2010年

使用find还可以直接返回纯文件以直接启动管道。
mpez0 2010年

1
您也可以使用Bash完全read代替Bash headfor file in *; do [ -f "$file" ] || continue; read < "$file"; [[ "$REPLY" =~ ^\<\? ]] || echo "$file"; done
janmoesen 2010年

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; 使用“查找-name'* .php'”。同样,危险地使用变量:使用“ find -exec your command'{}''+'”来避免“特殊”文件名的问题。除此之外,请始终引用变量:“ head -1” $ i“”,而不是“ head -1 $ i”。
janmoesen

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

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 "^<?"就足够了。
本杰明·班尼尔

1
对猫的无用用法:-(((
vwegert 2010年

没用的猫是没用的:(
user13743

我发现如果保持所有模块模块化并分解命令,记住命令要简单得多。我知道工作,但不知道是否command将文件作为参数。可能不是绝对必要,但我没有
删除

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"仅在出现问题时才打印文件名。
乔纳森·勒夫勒

2
那就是“ grep -q”的目的。:-)
janmoesen

0

我去看看

查找类型f | awk'
{
 if(getline ret <$ 0){
  if(ret〜“ ^ <\\?$”){
   打印“ Good [” $ 0“] [” ret“]”;
  }其他{
   打印“ Fail [” $ 0“]”;
  };
 }其他{
  打印“ empty [” $ 0“]”;
 };
 close($ 0);
}'

没有人说wak不可用:-)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.