逐行读取文件并删除字符shell脚本

时间:2014-05-06 03:25:49

标签: bash

该程序的目的是删除文本中的标点符号,并可以处理选项-c以删除所需的字符。

#!/bin/bash
old_IFS=$IFS
IFS=$’\n’
if [ “$1” == “-c” ];then
 if [ -f $2 ];then
  for line in $(<$2)
  do
   echo $line | tr -d $3
  done
  IFS=$old_IFS
 else
  echo $2 | tr -d $3
 fi
else
 if [ -f $1 ];then
  for line in $(cat $1)
  do
   echo $line | tr -d '[:punct:]'
  done
  IFS=$old_IFS
 else
   echo $1 | tr -d '[:punct:]'
 fi
fi

文本文件是:

"Twaddle!", you say?  I’ll have you know
there’s a {deep} truth
in what I said.

如果我只是想删除标点符号,结果是:

Twaddle you say  Ill have you k
iheres a deep truth
 what I said

其他字符丢失,例如now know。任何人都可以找到问题所在吗?

2 个答案:

答案 0 :(得分:1)

您遇到的困难是由于使用了非ASCII字符。特别要看:

IFS=$’\n’

该行无法正常工作,因为这些不是普通的ASCII单引号。结果是,n字符最终出现在变量IFS中。这导致n上的单词拆分,这就是nknow消失的原因。

改为使用:

IFS=$'\n'

双引号也是非标准的,应该用ASCII双引号替换。特别是,这一行:

if [ “$1” == “-c” ];then

应替换为:

if [ "$1" == "-c" ];then

替代脚本

脚本的逻辑可以重新排列和简化:

#!/bin/bash
remove='[:punct:]'
if [ “$1” == “-c” ]
then
    remove=$3
    shift
fi
if [ -f $1 ]
then
  tr -d "$remove" <"$1"
else
  echo "$1" | tr -d "$remove"
fi

答案 1 :(得分:0)

#!/bin/bash
if [ "$1" = '-c' ]
 then
   Pattern="$( echo "$3" | sed 's/[]\[&\\{}()"]/\\&/g' )"
   File="$2"
 else
   Pattern="[[:punct:]]"
   File="$1"
 fi
sed -i "s/${Pattern}//g" ${File}

使用sed,几乎没有关于脚本上“reduce”regex面板中的特殊字符的安全性