使用bash在文件中查找字符串

时间:2013-06-17 21:49:49

标签: linux bash

我需要找到匹配某些regexp pattern的字符串,并将搜索结果表示为数组,以便通过循环遍历它),我是否需要使用sed?一般来说,我想替换一些字符串,但在替换之前对它们进行分析。

3 个答案:

答案 0 :(得分:6)

使用seddiff

sed -i.bak 's/this/that/' input
diff input input.bak

GNU sed将在替换之前创建备份文件,diff将向您显示这些更改。但是,如果您不使用GNU sed

mv input input.bak
sed 's/this/that/' input.bak > input
diff input input.bak

使用grep的另一种方法:

pattern="/X"
subst=that
while IFS='' read -r line; do
    if [[ $line = *"$pattern"* ]]; then
        echo "changing line: $line" 1>&2
        echo "${line//$pattern/$subst}"
    else
        echo "$line"
    fi  
done < input > output

答案 1 :(得分:3)

执行此操作的最佳方法是使用grep获取行,并使用换行符作为内部字段分隔符填充结果数组:

#!/bin/bash

# get just the desired lines
results=$(grep "mypattern" mysourcefile.txt)

# change the internal field separator to be a newline
IFS=$'/n'

# populate an array from the result lines
lines=($results)

# return the third result
echo "${lines[2]}"

您可以构建一个循环来迭代数组的结果,但更传统和简单的解决方案就是使用bash的迭代:

for line in $lines; do
  echo "$line"
done

答案 2 :(得分:0)

仅供参考:这是我为了好玩而创建的类似概念。我认为如何使用这个来展示如何循环文件会很好。这是一个脚本,我查看Linux sudoers文件检查它包含我的valid_words数组列表中的一个有效单词。当然它忽略了评论&#34;#&#34;并且空白&#34;&#34;与sed的行。在这个例子中,我们可能只想打印无效行,但是这个脚本会打印两个。

#!/bin/bash

# -- Inspect a sudoer file, look for valid and invalid lines.

file="${1}"
declare -a valid_words=( _Alias = Defaults includedir )

actual_lines=$(cat "${file}" | wc -l)
functional_lines=$(cat "${file}" | sed '/^\s*#/d;/^\s*$/d' | wc -l)

while read line ;do

    # -- set the line to nothing "" if it has a comment or is empty line.
    line="$(echo "${line}" | sed '/^\s*#/d;/^\s*$/d')"

    # -- if not set to nothing "", check if the line is valid from our list of valid words.
    if ! [[ -z "$line" ]] ;then

        unset found 
        for each in "${valid_words[@]}" ;do
            found="$(echo "$line" | egrep -i "$each")"
            [[ -z "$found" ]] || break;
        done

        [[ -z "$found" ]] && { echo "Invalid=$line"; sleep 3; } || echo "Valid=$found"

    fi

done < "${file}"

echo "actual lines: $actual_lines  funtional lines: $functional_lines"