在bash中逐个字符读取用户提供的文件

6
我有一个文件,格式不规范,我想在每100个字符后面加上一个换行符,并删除其中的任何其他换行符,以便使该文件看起来具有一致的宽度和可读性。
此代码片段可帮助读取所有行。
 while read LINE
        do
                len=${#LINE}
                echo "Line length is : $len"
        done < $file

但是如何对字符执行相同的操作呢?

想法是创建类似这样的内容:(只是一个示例,可能存在语法错误,尚未实现)

 while read ch  #read character
  do
         chcount++ # increment character count

    if [ "$chcount" -eq "100" && "$ch"!="\n" ] #if 100th character and is not a new line
    then
        echo -e "\n" #echo new line
    elif [ "$ch"=="\n" ]  #if character is not 100th but new line
        then
        ch=" " $replace it with space
     fi
  done < $file

我正在学习 bash,请温柔点!

4个回答

7

bash 在标准的read命令中添加了一个-n 标志,用于指定要读取的字符数,而不是整行:

while read -n1 c; do
    echo "$c"
done < $file

我理解,n1 中的 1 是什么意思?它是否包括空格和换行符? - NoobEditor
1
“-n”需要一个强制参数; “-n2”将一次读取两个字符。 - chepner

7

我希望每100个字符后加入一个换行符,并删除其中的其他换行符,以使文件呈现出统一的宽度和可读性。

除非您有很好的理由编写脚本,否则可以直接进行操作而无需编写脚本。

从输入中删除换行符并折叠它。例如:

tr -d '\n' < inputfile | fold -w 100

应该实现所需的结果。

@NoobEditor 我现在因为时间不够而推迟了那个。话虽如此,重新发明轮子很少听起来令人信服。 - devnull
请告诉我你什么时候可以……耐心是我的美德……同时,如果我在网上找到了答案,就会删除这个问题! :) - NoobEditor
@NoobEditor 同时我会给你一个提示:read 会读取一行输入(该行不包含换行符)。 - devnull
抱歉这么晚才接受这个答案!_/\_ - NoobEditor

3
您可以以以下任何一种方式调用下面的函数:
line_length=100
wrap $line_length <<< "$string"
wrap $line_length < file_name
wrap $line_length < <(command)
command | wrap $line_length

该函数逐行读取输入(比逐字符更高效),从而基本上消除了现有的换行符(这些换行符将被替换为空格)。前一行的剩余部分会添加到当前行的前面,然后在所需的行长度处进行拆分。拆分后的剩余部分保留到下一次迭代。如果输出缓冲区已满,则输出并清除该缓冲区,否则将其保留到下一次迭代中以添加更多内容。一旦输入被消耗完,可能还会有剩余文本。当所有文本都被消耗并输出后,该函数会被递归调用。
wrap () { 
    local remainder rest part out_buffer line len=$1
    while IFS= read -r line
    do
        line="$remainder$line "
        (( part = $len - ${#out_buffer} ))
        out_buffer+=${line::$part}
        remainder=${line:$part}
        if (( ${#out_buffer} >= $len ))
        then
            printf '%s\n' "$out_buffer"
            out_buffer=
        fi
    done
    rest=$remainder
    while [[ $rest ]]
    do
        wrap $len <<< "$rest"
    done
    if [[ $out_buffer ]]
    then
        printf '%s\n' "$out_buffer"
        out_buffer=
    fi
}

看了你的回答,我现在意识到我完全不懂“Bash脚本”!!! :D - NoobEditor

1
#!/bin/bash
w=~/testFile.txt
chcount=0
while read -r word ; do
        len=${#word}
        for (( i = 0 ; i <= $len - 1 ; ++i )) ; do
                let chcount+=1
                if [ $chcount -eq 100 ] ; then
                        printf "\n${word:$i:1}"
                        let chcount=0
                else
                        printf "${word:$i:1}"
                fi
        done
done < $w

你是在寻找类似这样的东西吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接