Bash:从包含完整路径的读取行中提取用户路径(/home/userID),并替换为~&引用;

Bash:从包含完整路径的读取行中提取用户路径(/home/userID),并替换为~&引用;,bash,string-split,Bash,String Split,我一次构建一个bash脚本文件。我在学习 去吧。但在这一点上,我在网上找不到任何帮助我的东西:我需要 从一个大字符串中提取一个子字符串,我用${}(花括号)找到的两个方法就行不通了 第一个,${x#y},没有做它应该做的事情 第二个,${x:p}或${x:p:n},不断报告错误的替换。 它似乎只适用于常量 ${#x}以文本形式返回字符串长度,而不是以数字形式返回,这意味着它不能与${x:p}或${x:p:n}一起使用 事实上,让bash做很多数学似乎真的很难。除了for语句之外。但这只是计算而已

我一次构建一个bash脚本文件。我在学习 去吧。但在这一点上,我在网上找不到任何帮助我的东西:我需要 从一个大字符串中提取一个子字符串,我用
${}
(花括号)找到的两个方法就行不通了

第一个,
${x#y}
,没有做它应该做的事情

第二个,
${x:p}
${x:p:n}
,不断报告错误的替换。
它似乎只适用于常量

${#x}
以文本形式返回字符串长度,而不是以数字形式返回,这意味着它不能与
${x:p}
${x:p:n}
一起使用

事实上,让bash做很多数学似乎真的很难。除了for语句之外。但这只是计算而已。这不是for循环的任务

我在这里合并了我的脚本文件,以帮助大家理解我正在做什么。它用于处理PureBasic源文件,但您只需更改grep的“-include=”参数,它就可以搜索其他类型的文本文件

#!/bin/bash
home=$(echo ~)                              # Copy the user's path to a variable named home  
len=${#home}                                # Showing how to find the length.  Problem is, this is treated  
                                            # as a string, not a number.  Can't find a way to make over into  
                                            # into a number.  
echo $home "has length of" $len "characters."  
read -p "Find what: " what                  # Intended to search PureBasic (*.pb?) source files for text matches  
grep -rHn $what $home --include="*.pb*" --exclude-dir=".cache" --exclude-dir=".gvfs" > 1.tmp  
while read line                             # this checks for and reads the next line  
do                                          # the closing 'done' has the file to be read appended with "<"  
  a0=$line                                  # this is each line as read  
  a1=$(echo "$a0" | awk -F: '{print $1}')   # this gets the full path before the first ':'  
  echo $a0                                  # Shows full line  
  echo $a1                                  # Shows just full path  
  q1=${line#a1}  
  echo $q1                                  # FAILED!  No reported problem, but failed to extract $a1 from $line.  
  q1=${a0#a1}  
  echo $q1                                  # FAILED!  No reported problem, but failed to extract $a1 from $a0.  
  break                                     # Can't do a 'read -n 1', as it just reads 1 char from the next line.  
                                            # Can't do a pause, because it doesn't exist.  So just run from the  
                                            # terminal so that after break we can see what's on the screen  .
  len=${#a1}                                # Can get the length of $a1, but only as a string  
  # q1=${line:len}                          # Right command, wrong variable   
  # q1=${line:$len}                         # Right command, right variable, but wrong variable type  
  # q1=${line:14}                           # Constants work, but all $home's aren't 14 characters long  
done < 1.tmp  
#/bin/bash
home=$(echo~)#将用户的路径复制到名为home的变量
len=${home}显示如何查找长度。问题是,这是治疗
#作为字符串,而不是数字。找不到办法改成
#变成一个数字。
“echo$home”的长度为“$len”个字符
阅读-p“查找内容:”要搜索PureBasic(*.pb?)源文件以查找文本匹配的内容
grep-rHn$what$home--include=“*.pb*”--exclude dir=“.cache”--exclude dir=“.gvfs”>1.tmp
读行时,检查并读取下一行
do#结束语“done”将要读取的文件附加“以下工作:

x="/home/user/rest/of/path"
y="~${x#/home/user}"
echo $y
将输出

~/rest/of/path

如果你想在变量中使用“/home/user”,比如前缀,你需要在#之后使用$,也就是说,
${x#$prefix}
,我想这是你的问题。

我得到的hejp非常感谢。我完成了,现在它是:

#!/bin/bash
len=${#HOME}                                # Showing how to find the length.  Problem is, this is treated
                                            # as a string, not a number.  Can't find a way to make over into
                                            # into a number.
echo $HOME "has length of" $len "characters."
while :
do
  echo
  read -p "Find what: " what                # Intended to search PureBasic (*.pb?) source files for text matches
  a0=""; > 0.tmp; > 1.tmp
  grep -rHn $what $home --include="*.pb*" --exclude-dir=".cache" --exclude-dir=".gvfs" >> 0.tmp
  while read line                           # this checks for and reads the next line
  do                                        # the closing 'done' has the file to be read appended with "<"
    a1=$(echo $line | awk -F: '{print $1}') # this gets the full path before the first ':'
    a2=${line#$a1":"}                       # renove path and first colon from rest of line
    if [[ $a0 != $a1 ]]
    then
      echo  >> 1.tmp
      echo $a1":" >> 1.tmp
      a0=$a1
    fi
    echo " "$a2 >> 1.tmp
  done < 0.tmp
  cat 1.tmp | less
done
!/bin/bash
len=${HOME}显示如何找到长度。问题是,这被处理了
#作为字符串,而不是数字。找不到转换为的方法
#变成一个数字。
“echo$HOME”的长度为“$len”个字符
而:
做
回声
阅读-p“查找内容:”要搜索PureBasic(*.pb?)源文件以查找文本匹配的内容
a0=“”;>0.tmp;>1.tmp
grep-rHn$what$home--include=“*.pb*”--exclude dir=“.cache”--exclude dir=“.gvfs”>>0.tmp
读行时,检查并读取下一行

是否#结尾的“完成”将要阅读的文件附加了“如果你文章后半部分的评论是针对堆栈溢出的,那么我为你的挫败道歉;如果你愿意,我可以编辑你的文章,使其格式正确。对于许多用户来说,第一次发布比应该的要难,因为我们对发布格式和内容要求有非常特殊的规则。我建议删除问题的上述部分,因为这可能会吸引更多愿意回答的用户。更新:我已经编辑了你的帖子并清理了代码格式。如果我能做更多的事情让你的问题快速得到回答,并扭转你的沮丧情绪,我会的。你的字符串/数字类型的评论无效。我不知道你看到了什么让你困惑,但是使用
len=${a1};echo“${line:$len}”
工作正常。您可以省略算术上下文中变量的前导
$
(子字符串展开中
的右侧是),但这仅在结果为数字时有效(因此
${line}a1}
不起作用)。还要小心使用
~
,因为它不会以字符串等形式展开。使用
$HOME
可能是一个更好的主意(除非您需要
~user
格式展开,在这种情况下(除其他外)可能有用。