Я создаю файл сценария 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
len=${#a1}; echo "${line:$len}"
работает нормально. Вы можете опустить начальный$
для переменных в арифметическом контексте (что является правой частью:
в расширении подстроки), но это работает, только если результатом является число (поэтому${line#a1}
не будет работать). - person Etan Reisner   schedule 11.09.2015~
, так как он не раскрывается в строках/и т.д. Использование$HOME
может быть лучшей идеей (если вам не нужно расширение формата~user
, в этом случае этот ответ (среди прочего) может быть использования. - person Etan Reisner   schedule 11.09.2015