awk基础

https://github.com/wuzhouhui/awk/blob/master/The_AWK_Programming_Language_zh_CN.pdf 0. 实用一行手册 输入行的总行数 END { print NR } 打印第 10 行 NR == 10 打印每一个输入行的最后一个字段 { print $NF } 打印最后一行的最后一个字段 { field = $NF } END { print field } 打印字段数多于 4 个的输入行 NF > 4 打印最后一个字段值大于 4 的输入行 $NF > 4 打印所有输入行的字段数的总和 { nf = nf + NF } END { print nf } 打印包含 Beth 的行的数量 /Beth/ { nlines = nlines + 1 } END { print nlines } 打印具有最大值的第一个字段, 以及包含它的行 (假设 $1 总是 正的) 18 $1 > max { max = $1; maxline = $0 } END { print max, maxline } 打印至少包含一个字段的行 NF > 0 打印长度超过 80 个字符的行 length($0) > 80 在每一行的前面加上它的字段数 { print NF, $0 } 打印每一行的第 1 与第 2 个字段, 但顺序相反 { print $2, $1 } 交换每一行的第 1 与第 2 个字段, 并打印该行 { temp = $1; $1 = $2; $2 = temp; print } 将每一行的第一个字段用行号代替 { $1 = NR; print } 打印删除了第 2 个字段后的行 { $2 = ""; print } 将每一行的字段按逆序打印 printf("\n") }``` 18....

October 18, 2024 · 4 min · 李昌

vim技巧

1. 移动技巧 1.1 在同一行移动 首先是基本的hjkl 使用f<chat>来移动到当前行光标之后的字符上,这里可以选择一些出现频率较低的字符,这样有更高的移动效率。在使用f<char>后,,可以使用;来重复上次的查找移动,如果不小心多移动了一个,可以按,回退 使用w,e,b,ge在单词间跳转,其各自含义为: w 正向移动到下一单词的开头 b 反向移动到当前单词/上一单词的开头 e 正向移动到当前单词/下一单词的结尾 ge 反向移动到上一单词的结尾 w、b等是在单词间的跳转,但一个逗号或点也算单词,如果是想把一个用空格分隔的串叫做单词,可以使用W, B, E, gE gj, gk按屏幕行进行上下移动 1.2 在当前文件内移动 使用*跳转到当前文件内的当前光标下的单词 %跳转到匹配的括号 使用/执行常规搜索,并按n再次执行搜索 1.3 使用位置标记跳转 m<a-z>在当前文件中标记当前位置,mA-Z在全局定义一个mark '<a-zA-Z>跳转到刚才的缓冲区 vim还预置了一些特殊的标记: ''当前文件中,上次跳转之前的位置; '.上次修改的地方; '^ 上次插入的地方 '<, '> 上次高亮选区的起始和结束位置 1.4 在文件之间移动 <C-o>, <C-i>后退和前进 [count]G 跳转到某个行号, 例如40G跳转至40行 (, )跳转到上一句/下一句的开头, {, }跳转到上一段/下一段的开头 gf 跳转到光标下的文件名 <C-]> 跳转到光标下关键字的定义 改变列表, :changes查看最近的更改,g;和g,跳转到下一个和上一个更改 2. 选择技巧 在可视模式下的选择技巧...

July 3, 2024 · 3 min · 李昌

容器网络篇一:单机网络方案

安装工具: apt install bridge-utils net-tools 容器与宿主机的通信 创建一个新的网络命名空间,这里模拟容器内部的网络 $ ip netns add net1 # net1为该网络空间(容器内部网络空间)的名称 查看命名空间的iptable, 路由表,设备 $ ip netns exec net1 route # 查看容器内部路由表 Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface $ ip netns exec net1 iptables -L # 查看容器内部iptable Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination $ ip netns exec net1 ip link list # 查看容器内部设备 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 目前只有本地回环设备, 并且状态为DOWN(未启动) 创建一对veth,并将veth的一头添加到net1中...

February 28, 2024 · 4 min · 李昌

容器网络篇二:跨主机通信之Flannel

flannel项目本身只是一个框架,真正实现容器网络容器功能的,是Flannel的后端实现,目前,Flannel推荐的后端实现有四种,分别是: VXLAN host-gw WireGuard UDP 此外还有一些实验性的后端实现 UDP模式 UDP 模式,是最直接、也是最容易理解的容器跨主网络实现。 假设有两台宿主机: 宿主机 Node 1 上有一个容器 container-1,它的 IP 地址是 100.96.1.2,对应的 docker0 网桥的地址是:100.96.1.1/24。 宿主机 Node 2 上有一个容器 container-2,它的 IP 地址是 100.96.2.3,对应的 docker0 网桥的地址是:100.96.2.1/24。 现在的任务是:让container-1访问container-2。此时访问container-2的这个IP包的源地址为100.96.1.2,目的地址为100.96.2.1。按照上篇所述,首先这个IP包会通过veth对来到docker0网桥,而此时docker0网桥上并没有插入IP为100.96.1.2的设备,因此会走默认路由规则,出现在宿主机上。此时如果机器上已经安装了flannel,那么flannel会为宿主机创建出一系列路由规则,如: # 在Node 1上 $ ip route default via 10.168.0.1 dev eth0 100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0 100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1 10.168.0.0/24 dev eth0 proto kernel scope link src 10....

February 28, 2024 · 2 min · 李昌

拥抱大模型(三):OutputParser,格式化输出

大模型可以回答你的任何问题,但有时我们需要将大模型的回复进行格式化解析以便进行后续的处理,此时就需要我们使用一些特殊的技巧提示大模型:你应该如此如此,这般这般返回一个简单的例子(文心一言):可以看到,我们在prompt中告诉大模型,你应该以如下json格式返回,大模型按照我们的要求,切实返回了我们要求的json格式。这样,我们就可以把大模型的输出进行解析,大模型的输出,不再是无法解析的数据。langchain为我们提供了一系列工具来为prompt添加输出格式指令,解析输出,重试机制等等。 使用LangChain工具 PydanticOutputParser(json输出解析) from pydantic import BaseModel, Field from langchain.output_parsers import PydanticOutputParser, OutputFixingParser class FlowerDescription(BaseModel): title: str = Field(description="这本书的标题") author: int = Field(description="这本书的作者") words: str = Field(description="这本书的字数") description: str = Field(description="这本书的主要情节") # 定义输出解析器 output_parser = PydanticOutputParser(pydantic_object=FlowerDescription) # 获取输出格式指示 format_instructions = output_parser.get_format_instructions() print(format_instructions) The output should be formatted as a JSON instance that conforms to the JSON schema below. As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}} the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema....

February 4, 2024 · 2 min · 李昌

拥抱大模型(二):Prompt,给大模型有用的提示

极客时间《LangChain实战课》学习笔记 构建prompt的原则 原则(吴恩达版) 写出清晰而具体的提示 给模型思考的时间 原则(OpenAI版) 写清晰的指示 给模型提供参考(也就是示例) 将复杂任务拆分成子任务 给 GPT 时间思考 使用外部工具 反复迭代问题 prompt的基本结构 一个prompt主要包含四块内容: instruction(指令):告诉大模型要做什么,一个常见且有效的例子是,告诉大模型“你是一个XX专家” context(上下文):充当模型的额外知识来源,这些知识可以从矢量数据库中得来或通过其他方式拉入 prompt input (提示输入):具体的问题或大模型做的具体事情 output indicator(标记要生成的文本的开始):用一个明显的提示词让大模型开始回答,这一部分不是必须的 使用langchain构建prompt from langchain import PromptTemplate template = """\ 你是业务咨询顾问。 你给一个销售{product}的电商公司,起一个好的名字? """ prompt = PromptTemplate.from_template(template) print(prompt.format(product="鲜花")) prompt = PromptTemplate( input_variables=["product", "market"], template="你是业务咨询顾问。对于一个面向{market}市场的,专注于销售{product}的公司,你会推荐哪个名字?" ) print(prompt.format(product="鲜花", market="高端")) 二者效果相同构建chat prompt对于像ChatGPT这种聊天模型,langchain提供了ChatPromptTemplate,其中有多种角色类型: import openai openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "You are a helpful assistant....

February 4, 2024 · 2 min · 李昌

拥抱大模型(五):Memory,让大模型拥有记忆

要让大模型有记忆也很简单,你只需要把之前的对话传递给他就行,在ConversationChain中,就使用了这一技巧: from langchain import OpenAI from langchain.chains import ConversationChain # 初始化大语言模型 llm = OpenAI( temperature=0.5, model_name="text-davinci-003" ) # 初始化对话链 conv_chain = ConversationChain(llm=llm) # 打印对话的模板 print(conv_chain.prompt.template) 来看下模板: The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know. Current conversation: {history} Human: {input} AI: 可以看到,在模板里又一个history字段,这里存储了之前对话的上下文信息。当有了 {history} 参数,以及 Human 和 AI 这两个前缀,我们就能够把历史对话信息存储在提示模板中,并作为新的提示内容在新一轮的对话过程中传递给模型。—— 这就是记忆机制的原理。 langchain中提供的记忆机制 ConversationBufferMemory 在 LangChain 中,通过 ConversationBufferMemory(缓冲记忆)可以实现最简单的记忆机制。下面,我们就在对话链中引入 ConversationBufferMemory。...

February 4, 2024 · 2 min · 李昌

拥抱大模型(四):Chain,像人类一样思考

什么叫Chain,从字面意思理解,Chain是一个链,我们可以通过Chain来链接LangChain的各个组件和功能-模型之间彼此链接,或模型与其他组件链接。这种将多个组件相互链接,组合成一个链的想法简单但很强大。它简化了复杂应用程序的实现,并使之更加模块化,能够创建出单一的、连贯的应用程序,从而使调试、维护和改进应用程序变得容易。 我们可以简单的把Chain理解为通过设计好的一些链路去调用大模型,从而获取我们想要的结果。下面是一个例子: 首先我们让大模型扮演产品经理,给出小说推荐网站的产品设计。 有了产品设计后,由架构师进行初步的架构设计 现在架构设计也有了,来个程序员写SQL: 那,上面的这种promot链,我们用langchain怎么实现呢? 使用langchain实现 Sequential Chain 首先,导入所有需要的库 # 设置OpenAI API密钥 import os os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' from langchain.llms import OpenAI from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain.chains import SequentialChain 添加第一个LLMChain,生成小说网站的产品设计。LLMChain可以看作是链条的一个环节 # 这是第一个LLMChain,用于生成鲜花的介绍,输入为花的名称和种类 llm = OpenAI(temperature=.7) template = """ 你是一个产品经理,请你对{product}给出一个设计想法。""" prompt_template = PromptTemplate(input_variables=["product"], template=template) introduction_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="introduction") 添加第二个LLMChain,根据产品设计生成软件架构 # 这是第二个LLMChain,用于根据鲜花的介绍写出鲜花的评论 llm = OpenAI(temperature=.7) template = """ 你是一位软件架构师。给定一个{product}的设计,你需要给出产品软件架构说明和技术栈选型。 产品设计: {introduction} 软件架构说明:""" prompt_template = PromptTemplate(input_variables=["product", "introduction"], template=template) review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="framwork") 第三个Chain,根据产品架构生成SQL语句...

February 4, 2024 · 5 min · 李昌

Function as a Method Receiver

通常来说,我们会使用某个具体的对象(struct)来作为receiver实现接口,但有时候,使用函数作为receiver可以起到不一样的效果。 使用函数作为receiver一个最常见的例子是HandleFunc: type HandlerFunc func(ResponseWriter, *Request) func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) } 这里将HandleFunc作为接收器,实现了ServeHTTP方法,同时也实现了http.Handler接口 type Handler interface { ServeHTTP(ResponseWriter, *Request) } 代码注释中对与HandleFunc的解释如下: // The HandlerFunc type is an adapter to allow the use of // ordinary functions as HTTP handlers. If f is a function // with the appropriate signature, HandlerFunc(f) is a // Handler that calls f. HandleFunc的定位是:适配器。为什么这么说?有了这个适配器,我们就可以这样完成一个http server: func main() { http.HandleFunc("/echo", func(w http.ResponseWriter, r *http....

November 26, 2023 · 1 min · 李昌

Linux命令之nc

nc: 任意的TCP/UDP连接和监听 It can open TCP connections, send UDP packets, listen on arbitrary TCP and UDP ports, do port scanning, and deal with both IPv4 and IPv6. 使用case 快速创建client/server对 nc -l 1234 nc 127.0.0.1 1234 任何在client端的输出都将在server端显示 端口扫描 nc -zv 127.0.0.1 8885-8889 其他例子 nc -p 31337 -w 5 abc.com 42 nc -u abc.com 53 nc -s 10.1.2.3 abc.com 42 nc -lU /var/tmp/dsocket

November 26, 2023 · 1 min · 李昌