简体   繁体   English

如何通过 `awk` 或 `sed` 在 Ubuntu 终端变量的末尾添加一些字符?

[英]How do I add some characters at the end of an Ubuntu terminal variable via `awk` or `sed`?

Context语境

I am currently trying to setup Windows Subsystem 2 for Linux in my Windows 10 Pro OS.我目前正在尝试在我的 Windows 10 Pro OS 中为 Linux 设置 Windows 子系统 2。 After downloading Ubuntu 20.04 LTS from the Microsoft store, installing it, and creating my user profile, I started wondering how I could run and use all the Ubuntu programs that have a graphical interface.从 Microsoft 商店下载 Ubuntu 20.04 LTS、安装它并创建我的用户配置文件后,我开始想知道如何运行和使用所有具有图形界面的 Ubuntu 程序。 I then discovered Xming , which allowed me to establish a connection between my Windows OS and the Ubuntu kernel via IP: everything works fine, except for the fact that since there is no way to set a static IP for the WSL virtual ethernet card, every time I restart my PC I have to check and change the address to which I want to connect. I then discovered Xming , which allowed me to establish a connection between my Windows OS and the Ubuntu kernel via IP: everything works fine, except for the fact that since there is no way to set a static IP for the WSL virtual ethernet card, every当我重新启动我的电脑时,我必须检查并更改我想要连接的地址。 I am currently doing this by editing each time my .bashrc file, and adding a line like我目前正在通过每次编辑我的.bashrc文件并添加一行来执行此操作

export DISPLAY=172.29.112.1:0.0

which corresponds to the IP I have listed in the IPv4 sub-section of the WSL web configuration.它对应于我在 WSL web 配置的 IPv4 小节中列出的 IP。 I obtained it by running我通过运行获得它

ipconfig

inside a PowerShell/Windows terminal.在 PowerShell/Windows 终端内。 The two zeroes I added to the IP are the ports requested by Xming , (and also, indirectly, the cause of my problem).我添加到 IP 的两个零是Xming请求的端口,(也间接地,我的问题的原因)。

My idea has been to try and automate all this process, so that every time I boot my PC I just have to launch Xming and Ubuntu.我的想法是尝试自动化所有这些过程,这样每次启动 PC 时,我只需要启动Xming和 Ubuntu。

Issue description问题描述

The problem is that I had close to zero knowledge about terminal syntax, so I managed to come up with just a partial solution: I managed to automatically load the correct IP, but I cannot append the ports without deleting part of the IP itself.问题是我对终端语法的了解几乎为零,所以我设法提出了一个部分解决方案:我设法自动加载正确的 IP,但是我不能 append 端口而不删除 ZA12A3079E14CED42B1BAZ05 本身的一部分。 This is what I came up with so far:到目前为止,这是我想出的:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | grep IPv4 | cut -d: -f2 | awk '{print $1}' | awk 'END{print}')

This line, added to my .bashrc , allows me to get the correct IPv4, which happens to always be the one at the end of the list (hence the second awk call).添加到我的.bashrc的这一行允许我获得正确的 IPv4,它恰好总是位于列表末尾的那个(因此是第二个awk调用)。 It invokes the same ipconfig one uses inside Windows, so that I can obtain the desired address.它调用 Windows 内部使用的相同ipconfig ,这样我就可以获得所需的地址。 I studied a bit how this syntax works and found some interesting solutions to the next problem, ie attaching the ':0.0' at the end of the query above.我研究了一下这个语法是如何工作的,并为下一个问题找到了一些有趣的解决方案,即在上面的查询末尾附加':0.0'。 One, for instance, is this .例如,一个是this Unfortunately, even if replicating that solution works fine with normal strings, it seems like my IP address is stored as a different kind of variable, or at least it behaves differently: trying to apply that same concept makes so that the initial portion of my IP gets overwritten.不幸的是,即使复制该解决方案适用于普通字符串,我的 IP 地址似乎存储为不同类型的变量,或者至少它的行为不同:尝试应用相同的概念使得我的 IP 的初始部分被覆盖。

What I want我想要的是

A (possibly) one-line formula like the one I made, but which also incorporates the ports at the end, without overwriting any of the IP's digits.一个(可能)像我做的那样的单行公式,但它也包含最后的端口,而不会覆盖任何 IP 的数字。 In any case, the DISPLAY variable assigned in the .bashrc must be of the same type of the current one I have with my partial implementation, as I need it to be read by Xming , or any other program.在任何情况下,在.bashrc中分配的DISPLAY变量必须与我的部分实现中的当前变量的类型相同,因为我需要它由Xming或任何其他程序读取。 I would also appreciate some explanations about the solution and about the reason of the overwriting phenomenon I described.我还希望对解决方案以及我描述的覆盖现象的原因进行一些解释。

What I have tried so far到目前为止我尝试过的

I have devoted all the afternoon to this issue, starting from learning a little bit of the syntax of the Ubuntu terminal, as well as trying to find examples of sed and awk , among other functions.我花了一个下午的时间来解决这个问题,从学习一点Ubuntu终端的语法开始,以及试图找到sedawk等函数的例子,等等I also tried many slightly altered versions of my query in order to fit in the ports, but all these tries only yielded syntax errors or the same overwriting effect described above.为了适应端口,我还尝试了许多稍微修改过的查询版本,但所有这些尝试只产生了语法错误或上述相同的覆盖效果。

Why I am asking this为什么我要问这个

Given that I expect this to take me probably a little while to solve, and that I am confident this should not be time-consuming at all for anybody with some experience in the field, I hope to receive some help.鉴于我预计这可能需要我一段时间才能解决,并且我相信对于任何具有该领域经验的人来说这根本不应该是耗时的,我希望得到一些帮助。

Thank you!谢谢!

Update更新

After several tries, it turns out that the WSL IP sub-category could indeed be listed in a different position than last.经过几次尝试,事实证明 WSL IP 子类别确实可以列在与上一个不同的 position 中。 I thought the entries would follow the alphabetical order, but it is clear now that that was just a coincidence.我原以为这些条目会按照字母顺序排列,但现在很明显这只是一个巧合。
Thus, if I have something like this:因此,如果我有这样的事情: WSL IP 小节

I now have the need to actually grep this precise portion of the ipconfig output, rather than blindly picking the last of the list as I have been doing until now.我现在实际上需要grep这个ipconfig output 的精确部分,而不是像我一直在做的那样盲目地选择列表的最后一个。 I have tried to wrap my head around your solutions, and with some further research I managed to find a way to make it work regardless of the postioning:我试图围绕您的解决方案展开我的头脑,并且通过一些进一步的研究,我设法找到了一种使其工作的方法,而不管定位如何:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | awk '/WSL/{getline; getline; getline; getline; print}' | grep IPv4 | cut -d: -f2 | tail -n1 | sed 's/\r//g' | awk 'END {print($1":0.0");}')

obtained attaching @Zilog80 formula.获得附加@Zilog80 公式。 What I understood is that getline should read and ignore the current line and move to the next one, so by doing that 4 times I could apply the rest of the formula to the line I was originally interested in. There are surely better ways to do it, but I can confirm that this is pretty reliable, even if not elegant.我的理解是getline应该读取并忽略当前行并移至下一行,因此通过这样做 4 次,我可以将公式的 rest 应用于我最初感兴趣的行。肯定有更好的方法来做它,但我可以确认这是非常可靠的,即使不优雅。 Looking forward to see your suggestion/improvements also for this update.期待看到您对此更新的建议/改进。

ps I removed part of the IPv6 as I am not aware if that is sensible information; ps 我删除了部分 IPv6,因为我不知道这是否是明智的信息; sorry if that was not the case.抱歉,如果不是这样。

The issue you have come from the fact that you're are launching ipconfig.exe, a windows tools for ip adapters, which output with Windows line terminators (CR+LF). The issue you have come from the fact that you're are launching ipconfig.exe, a windows tools for ip adapters, which output with Windows line terminators (CR+LF). That drives AWK to keep the CR in the output, thus overwriting .这驱动AWK将 CR 保留在 output 中,从而overwriting .

To prevent that, filter the damn CR with the sed utility, which permits to remove the troubling CR (\r):为防止这种情况,请使用sed实用程序过滤该死的 CR,该实用程序允许删除麻烦的 CR (\r):

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | grep IPv4 | cut -d: -f2 | tail -n1 | sed 's/\r//g' | awk 'END {print($1":0.0");}')

As @Ed Morton suggested, it may be useful to let know that all your command can be done with AWK only:正如@Ed Morton 所建议的那样,让您知道您的所有命令都可以仅使用AWK完成可能很有用:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | awk -F\: '/IPv4/{adr=$NF}END{sub(/\r$/,"",adr); print adr":0:0"}')

Here's a shorter one-liner leveraging @Zilog80's point about the carriage return:这是利用@Zilog80 关于回车的观点的更短的单行:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe| awk '/IPv4/ {addr=$NF} END {printf "%.*s:0.0", length(addr)-1, addr}')

This searches for the lines that have "IPv4" embedded in them and captures the last whitespace-delimited item on the line.这将搜索其中嵌入了“IPv4”的行,并捕获该行中最后一个以空格分隔的项目。 At the end, it prints it out, restricting the string to the first length-1 characters (which deletes the carriage return).最后,它打印出来,将字符串限制为第一个长度为 1 的字符(这会删除回车)。

Sorry, I haven't read all parts, only your issue description and "what I want".抱歉,我没有阅读所有部分,只有您的问题描述和“我想要的”。 This should help you:这应该可以帮助您:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | sed 's/\r$//' | awk '/IPv4/{ip=$NF}END{print ip ":0:0"}')
  • Your windows command gives DOS line endings.您的 windows 命令给出 DOS 行结尾。 I convert them with sed .我用sed转换它们。
  • awk stores the last field of all lines containing IPv4 in the variable ip which gets printed in the end. awk 将包含IPv4的所有行的最后一个字段存储在最后打印的变量ip中。
  • awk can concatenate strings: print ip ":0:0" awk 可以连接字符串: print ip ":0:0"

PS: Don't forget to replace the previously appended line in your .bashrc . PS:不要忘记替换.bashrc中先前附加的行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用sed或awk,如何从当前行的末尾匹配回指定的字符? - With sed or awk, how do I match from the end of the current line back to a specified character? 如何使用sed在ubuntu中的文件末尾添加多个换行符 - How to add multiple newlines at end of a file in ubuntu using sed Sed / awk-如何删除开始模式和结束模式之间的换行符。 - Sed/awk - How to remove newline characters between start pattern and end pattern. 如何在sed或awk中的分隔符上拆分多个单词 - How do I split a number of words on delimiter in sed or with awk sed如何在第一行的末尾添加带有竖线的变量 - Sed how to add variable with vertical bar to the end of first line 我如何在Awk Ubuntu中添加两列字符串(整数)? - how to i add two columns in Awk Ubuntu that are strings(which are integers)? Linux bash:sed、awk 等工具匹配行尾正则表达式“$”作为终端宽度 - Linux bash: sed, awk, etc tools are matching end of line regex '$' as the terminal width 如何使用sed搜索和替换,而不包括一组字符? - How do i search & replace using sed and not include a group of characters? 如何遍历通过终端传递给Ruby脚本的bash数组变量的元素? - How do I loop through elements of a bash array variable passed to a Ruby script via terminal? 如何使用sed替换退格符(\\ b)? - How do I replace backspace characters (\b) using sed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM