在一段时间的读取循环中,我看到了这个变量扩展${line/device name:}.我已经尝试使用自己的输入文件运行脚本,它只打印出行.
你能告诉我扩展在做什么吗?
有没有办法!$在参数扩展上下文中使用?促使这个问题的期望用法是快速(就关键笔划而言)文件名称的更改(例如,不是将文件名保存在变量中并执行rsvg-convert $svg > ${svg/.svg/.png},而是可以改为使用rsvg-convert $! > $!{/.svg/.png},其中$!{/.svg/.png}错误的语法暗示所需的当有问题的文件是前一行的最后一个标记时,这种命令通常可以比在存在共享不同长度的前缀的文件时使用标签完成或者通过复制和粘贴文件名来更快地输入.用鼠标选择).据我所知,没有办法!$在这样的背景下使用,但也许通过一些诡计可以实现类似的效果.
我很难记住哪一个参数扩展${var%subst}或${var#subst}从字符串的前面删除,哪一个从字符串的后面删除。例子:
$ var=/a/b/c
$ echo dirname=${var#/*} filename=${var%%*/}
dirname=a/b/c filename=/a/b/c # Wrong!
$ echo dirname=${var%/*} filename=${var##*/}
dirname=/a/b filename=c
Run Code Online (Sandbox Code Playgroud)
我总是将它们混合在一起,最终要么编写一些测试命令,要么查看手册。很容易记住%%删除 more then %,因为then%%是一个更长的字符串%,2 个字符 vs 1 个字符,与##vs相同#。但我总是%和#.
是否有内存规则可以知道字符串的哪一端%或#从哪一端删除?
为什么不能扩展参数类型?
auto lambda = []() { return 'c'; };
template <typename ... Ts>
struct MyClass
{
};
template <typename ... Ts>
void createMyClass(Ts&& ... ts)
{
/* SUPPOSED TO CREATE MY CLASS WITH THE RETURN VALUES OF THE CALLABLES */
MyClass< (decltype(std::declval<Ts>()()), ...)> d;
}
int main()
{
createMyClass(lambda, lambda);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
decltype(std::declval<Ts>()())应该从调用中获取返回值的类型Ts。然后我尝试通过在它后面执行 , ... 并将其括在括号中来扩展它,这是一个折叠表达式。与我正在寻找的内容本质上等效的是MyClass<return_type1, return_type2, return_type_n>.
"syntax error: ',' was unexpected here
Run Code Online (Sandbox Code Playgroud)
和
syntax error: unexpected token '...' following 'statement'
Run Code Online (Sandbox Code Playgroud) $ set a b c
$ echo $1 $2 $3
a b c
$ echo ${1..3}
-bash: ${1..3}: bad substitution
Run Code Online (Sandbox Code Playgroud)
我希望通过支撑扩展来回收$ 1 $ 2 $ 3.但它不起作用.
扩展的顺序是:括号扩展,波浪扩展,参数,变量和算术扩展和命令替换(以从左到右的方式完成),单词拆分和路径名扩展.
根据bash手册,在参数扩展之前执行支撑扩展.
所以我认为bash应首先执行大括号扩展${1..3},将其转换为echo $1 $2 $3,然后执行参数扩展.
然而,事实是bash抱怨${1..3}是一个糟糕的替代品.这是为什么?
PS:谢谢你们!你们的回答都很精彩.但我想
Ignacio Vazquez-Abrams的答案更接近我想要的.
为了调试我的脚本,我想在每个输出的开头添加内部变量$ FUNCNAME和$ LINENO,所以我知道输出发生在哪个函数和行号上.
foo(){
local bar="something"
echo "$FUNCNAME $LINENO: I just set bar to $bar"
}
Run Code Online (Sandbox Code Playgroud)
但是由于会有很多调试输出,如果我可以执行以下操作,它会更清晰:
foo(){
local trace='$FUNCNAME $LINENO'
local bar="something"
echo "$trace: I just set bar to $bar"
}
Run Code Online (Sandbox Code Playgroud)
但上面的字面输出:"$ FUNCNAME $ LINENO:我只是设置了一些东西"我认为这样做是因为双引号只扩展了一次内部的变量.
是否有一种语法上干净的方法在同一行中扩展变量两次?
linux bash parameter-passing variable-expansion parameter-expansion
我在 Linux shell 中有一个字符串。该字符串中包含下划线。
我想从字符串中提取一个子字符串。
我想提取第三次出现下划线之后的子字符串(从字符串末尾算起)。
file_name='email_Tracking_export_history_2018_08_15'
string_name="${file_name#*_*_*_}"
file_name2='email_Tracking_export_2018_08_15'
string_name2="${file_name2#*_*_*_}"
echo "$string_name"
echo "$string_name2"
Run Code Online (Sandbox Code Playgroud)
结果
history_2018_08_15
2018_08_15
Run Code Online (Sandbox Code Playgroud)
如您所见,string_name="${file_name#*_*_*_}"无法正常工作。
期望的结果:
2018_08_15
2018_08_15
Run Code Online (Sandbox Code Playgroud)
我怎样才能达到我想要的结果?
我正在寻找一个单行代码来替换变量字符串中变量字符串中变量位置的任何字符。我想出了这个工作解决方案:
echo "$string" | sed "s/./${replacement}/${position}"
Run Code Online (Sandbox Code Playgroud)
示例用法:
string=aaaaa
replacement=b
position=3
echo "$string" | sed "s/./${replacement}/${position}"
aabaa
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我使用包含我当前解决方案的脚本运行 shellcheck 时,它告诉我:
SC2001: See if you can use ${variable//search/replace} instead.
Run Code Online (Sandbox Code Playgroud)
我想使用它建议的参数扩展而不是管道到 sed,但我不清楚使用位置变量时的正确格式。在官方文档似乎并没有讨论在所有字符串中的定位。
这可能吗?
我目前正在试验可变参数模板,因为我正在尝试将可变参数类模板用于我正在处理的项目。我希望该类接受一个整数列表,这些整数将用于创建该类的其他元素。最初,我使用模板构造函数来获取整数数组。但是,我在链接代码时遇到了问题。我想出了一种使用可变参数类模板来获取整数列表来解决我的问题的替代方法,但是我很好奇这段代码是否被认为是糟糕的 C++(我有一段时间没有编写 C++,这感觉很hacky)。无论如何,这是我编写的测试代码,它按预期编译和工作:
template<int...structure>
class testClass{
public:
testClass(){
std::size_t size = sizeof...(structure);
std::cout << size << '\n';
int arr[]{ structure... };
for (int i = 0; i < size; i++)
std::cout << arr[i] << '\n';
}
};
int main() {
testClass<1, 2, 3> c;
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,代码输出:
3
1
2
3
Run Code Online (Sandbox Code Playgroud)
这个解决方案有什么问题吗?我一直在网上搜索,似乎没有人以这种方式使用可变参数模板。
提前感谢您的意见。
并不重要 - 但我正在尝试更深入地了解 bash 脚本,这让我发疯!
我的目标 - 在 bash 脚本中:
如果 $args 中没有空格,没问题 - 但这里有一个最小的脚本来说明:
#!/bin/bash
function tstArgs () {
echo "In tstArgs: ArgCnt:$#; Arg1:[$1]; Arg2:[$2]"
}
ARG1=today
ARG2=tomorrow
CMD1="tstArgs $ARG1 $ARG2"
$CMD1 #Output - As Desired: In tstArgs: ArgCnt:2; Arg1:[today]; Arg2:[tomorrow]
ARGWS1="'today with spaces'"
ARGWS2="'tomorrow with spaces'"
CMD2="tstArgs $ARGWS1 $ARGWS2"
$CMD2 #Output: In tstArgs: ArgCnt:6; Arg1:[today]; Arg2:[with]
#The dream:
ARGARR=($ARGWS1 $ARGWS2)
CMD3="tstArgs ${ARGARR[@]}"
$CMD3 #Output: In tstArgs: ArgCnt:6; Arg1:[today]; Arg2:[with]
#ETC, ETC, ETC... …Run Code Online (Sandbox Code Playgroud)